package com.jhhc.StormSurgeForecast.Calculate.Controller;

import cn.hutool.core.lang.UUID;
import com.jhhc.RHDB.Data.Pojo.ST_RIVER_R;
import com.jhhc.RHDB.Data.Pojo.ST_TIDE_R;
import com.jhhc.RHDB.Data.Service.BdmsStatisticalDataService;
import com.jhhc.RHDB.Data.Service.ST_RIVER_RService;
import com.jhhc.RHDB.Data.entity.BdmsStatisticalData;
import com.jhhc.RHDB.RiverForecast.Calculate.entity.HY_DQ_C;
import com.jhhc.RHDB.RiverForecast.Calculate.service.HY_DQ_CService;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Pojo.*;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Service.BDMS_CALCULATESCHEME_MService;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Service.BDMS_FBC_TFPATH_FService;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Service.BDMS_FBC_TFPATH_RService;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Service.BDMS_ST_ASTROTD_FService;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Util.TimeObject;
import com.jhhc.StormSurgeForecast.AstronomicalTide.Util.TimeUtil;
import com.jhhc.StormSurgeForecast.Calculate.BO.CenterUrl;
import com.jhhc.StormSurgeForecast.Calculate.BO.ModelConfig;
import com.jhhc.StormSurgeForecast.Calculate.DTO.ModelParam;
import com.jhhc.StormSurgeForecast.Calculate.Service.ModelService;
import com.jhhc.StormSurgeForecast.Calculate.util.*;
import com.jhhc.StormSurgeForecast.StormSurge.Pojo.FBC.BDMS_FBC_OCEANMODEL_B;
import com.jhhc.StormSurgeForecast.StormSurge.Pojo.FBC.BDMS_FBC_RESULT_A;
import com.jhhc.StormSurgeForecast.StormSurge.Service.BDMS_FBC_OCEANMODEL_BService;
import com.jhhc.StormSurgeForecast.StormSurge.Service.BDMS_FBC_RESULT_AService;
import com.jhhc.utils.JsonResult;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author LYQ
 */
@RestController
@RequestMapping(value = "StormSurgeForcast/Calculate")
@RequiredArgsConstructor
public class ModelController {

    private final BDMS_FBC_OCEANMODEL_BService bdms_fbc_oceanmodel_bService;

    private final BDMS_FBC_TFPATH_FService bdmsFbcTfpathFService;

    private final BDMS_FBC_TFPATH_RService bdmsFbcTfpathRService;

    private final BDMS_CALCULATESCHEME_MService bdms_calculatescheme_mService;

    private final BDMS_FBC_RESULT_AService bdms_fbc_result_aService;

    private final BDMS_ST_ASTROTD_FService bdmsStAstrotdFService;

    private final ModelService modelService;

    private final ModelConfig modelConfig;

    private final ST_RIVER_RService stRiverRService;

    private final HY_DQ_CService hyDqCService;

    private final BdmsStatisticalDataService bdmsStatisticalDataService;
    /**
     *模型计算
     */
    @RequestMapping(value = "/Forecast/Run",method = RequestMethod.POST,headers = "Accept=application/json")
    public JsonResult run(@RequestBody ModelParam param) throws ParseException {
        JsonResult jsonResult = new JsonResult();
        jsonResult.setStatusCode(200);
        jsonResult.setSucceeded(true);
        //查询对应模型
        BDMS_FBC_OCEANMODEL_B bdmsFbcOceanmodelB = bdms_fbc_oceanmodel_bService.getModelInfo(Integer.valueOf(param.getProjectId()), param.getModelId());
        if (bdmsFbcOceanmodelB == null || "".equals(bdmsFbcOceanmodelB.getModelid())) {
            jsonResult.setRemark("查询模型信息失败");
            return jsonResult;
        }
        String uuid = UUID.randomUUID().toString();
        TimeUtil timeUtil = new TimeUtil();
        CalUtil calUtil = new CalUtil();
        if (modelConfig.getType() == 1) {
            String jobId = "";//作业id
            String jobStatus = "";//作业状态
            String code = "";//上传文件状态
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String token = calUtil.getToken(modelConfig);//获取token
            if (token == null || "".equals(token)) {
                jsonResult.setRemark("获取token失败");
                return jsonResult;
            }
            CenterUrl centerUrl = calUtil.getCenter(token,modelConfig);//获取授权区域地址center
            String cschemePath = modelConfig.getUserpathname() + "model/caltmp/" + uuid;
            //使用uidu创建文件夹,返回作业id
            jobId = calUtil.createFolder(centerUrl.getHpcUrl(), token, cschemePath, modelConfig);
            if (jobId != null && !"".equals(jobId)) {
                jobStatus = calUtil.queryJobs(centerUrl.getHpcUrl(), token, jobId);
                //查询作业状态
                while (!"statC".equals(jobStatus)) {
                    try {
                        TimeUnit.SECONDS.sleep(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                        System.out.println("线程暂停异常");
                    }
                    jobStatus = calUtil.queryJobs(centerUrl.getHpcUrl(), token, jobId);
                    System.out.println("等待作业完成中...");
                }
                //复制模型文件到计算方案文件夹下（uuid）
                String modelPath = modelConfig.getUserpathname() + "model/" + bdmsFbcOceanmodelB.getFoldernm();
                jobId = calUtil.copyFolder(centerUrl.getHpcUrl(), token, cschemePath, modelConfig, modelPath);
                if (jobId != null && !"".equals(jobId)) {
                    //查询作业状态
                    jobStatus = calUtil.queryJobs(centerUrl.getHpcUrl(), token, jobId);
                    //查询作业状态
                    while (!"statC".equals(jobStatus)) {
                        try {
                            TimeUnit.SECONDS.sleep(2);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                            System.out.println("线程暂停异常");
                        }
                        jobStatus = calUtil.queryJobs(centerUrl.getHpcUrl(), token, jobId);
                        System.out.println("等待作业完成中...");
                    }
                    //实测路径
                    List<BDMS_FBC_TFPATH_R> bdmsFbcTfpathRs;
                    CreateFileUtil createFileUtil = new CreateFileUtil();
                    UploadUtil uploadUtil = new UploadUtil();
                    String localPath = modelConfig.getLocalPath() + File.separator + uuid;
                    File tfpath;
                    String linuxPath = cschemePath + "/" + bdmsFbcOceanmodelB.getFoldernm();
                    File astrotd;
                    File tide;
                    String workPath = cschemePath + "/" + bdmsFbcOceanmodelB.getFoldernm();
                    BDMS_CALCULATESCHEME_M1 bdmsCalculateschemeM1;
                    List<BDMS_ST_ASTROTD_F> fList;
                    List<ST_TIDE_R> rList;
                    String nhupStart;
                    String nhupEnd;
                    List<BDMS_FBC_TFPATH_F> bdmsFbcTfpathFs;
                    File nhup;
                    String startTime;
                    String endTime;
                    switch (bdmsFbcOceanmodelB.getModelid()) {
                        case "HHUCCHAOSUAN"://东海曙光超算+构造风场
                        case "HoHaiEastSeaZS"://东中国海模型
                        case "HoHaiSouthSeaZs"://南中国海模型
                        case "JSCoastSurge"://江苏沿海增水模型
                            if ("实际".equals(param.getTyphoonDepart())) {
                                bdmsFbcTfpathRs = bdmsFbcTfpathRService.queryByTfid(param.getTfid());
                                if (bdmsFbcTfpathRs == null || bdmsFbcTfpathRs.size() == 0) {
                                    jsonResult.setRemark("获取台风实测路径失败");
                                    return jsonResult;
                                } else if (format.parse(bdmsFbcTfpathRs.get(bdmsFbcTfpathRs.size() - 1).getYmdhm()).
                                        compareTo(format.parse(param.getForecastTime())) == 0) {
                                    jsonResult.setRemark("该台风实测路径为最后的实测路径点，无法后报");
                                    return jsonResult;
                                }
                                //生成tfpath.dat文件
                                tfpath = calUtil.createTfpathFileH(bdmsFbcTfpathRs,localPath);
                                //上传tfpath.dat文件
                                code = calUtil.fileUpload(centerUrl.getEfileUrl(), token, tfpath, linuxPath);
                                if (code != null && Objects.equals(code, "0")) {
                                    System.out.println("上传成功");
                                } else {
                                    jsonResult.setRemark("上传tfpath.dat文件失败");
                                    return jsonResult;
                                }
                                //生成nhup1.txt文件
                                nhupStart = param.getForecastTime();
                                nhupEnd = bdmsFbcTfpathRs.get(bdmsFbcTfpathRs.size() - 1).getYmdhm();
                                nhup = calUtil.createNhup1File(nhupStart, localPath, nhupEnd,
                                        param.getModelPar(), param.isArea(), bdmsFbcOceanmodelB);
                                //上传nhup1.txt文件
                                code = calUtil.fileUpload(centerUrl.getEfileUrl(), token, nhup, linuxPath);
                                if (code != null && Objects.equals(code, "0")) {
                                    System.out.println("上传成功");
                                } else {
                                    jsonResult.setRemark("上传nhup1.txt文件失败");
                                    return jsonResult;
                                }
                                //提交模型计算作业
                                jobId = calUtil.modelCalculate(centerUrl.getHpcUrl(), token, modelConfig, workPath);
                                bdmsCalculateschemeM1 = calUtil.insertProject(param, uuid,
                                        bdmsFbcOceanmodelB, bdmsFbcTfpathRs.get(bdmsFbcTfpathRs.size() - 1).getYmdhm(), jobId);
                                bdms_calculatescheme_mService.insertBdmsCalculateschemeM(bdmsCalculateschemeM1);
                            }else {
                                //预报路径
                                bdmsFbcTfpathFs = bdmsFbcTfpathFService.forecastPath(param.getTfid(),
                                        param.getTyphoonDepart(), param.getForecastTime());
                                if (bdmsFbcTfpathFs == null || bdmsFbcTfpathFs.size() == 0) {
                                    jsonResult.setRemark("该台风实测路径点没有对应的中国台预见期数据");
                                    return jsonResult;
                                }
                                for (BDMS_FBC_TFPATH_F fbcTfpathF : bdmsFbcTfpathFs) {
                                    if (fbcTfpathF.getPressure() == null || fbcTfpathF.getPressure() == 0) {
                                        jsonResult.setRemark("预报路径气压数据不完整");
                                        return jsonResult;
                                    }
                                }
                                bdmsFbcTfpathRs = bdmsFbcTfpathRService.getTyphoonIdPath(param.getTfid(),
                                        param.getForecastTime());
                                if (bdmsFbcTfpathRs == null || bdmsFbcTfpathRs.size() == 0) {
                                    jsonResult.setRemark("获取台风实测路径失败");
                                    return jsonResult;
                                }
                                //生成tfpath.dat文件
                                tfpath = calUtil.createTfpathFile(bdmsFbcTfpathRs, bdmsFbcTfpathFs,
                                        localPath,param.getForecastTime());
                                //上传tfpath.dat文件
                                code = calUtil.fileUpload(centerUrl.getEfileUrl(), token, tfpath, linuxPath);
                                if (code != null && Objects.equals(code, "0")) {
                                    System.out.println("上传成功");
                                } else {
                                    jsonResult.setRemark("上传tfpath.dat文件失败");
                                    return jsonResult;
                                }
                                //生成nhup1.txt文件
                                nhupStart = param.getForecastTime();
                                nhupEnd = bdmsFbcTfpathFs.get(bdmsFbcTfpathFs.size() - 1).getForecasttm();
                                nhup = calUtil.createNhup1File(nhupStart, localPath, nhupEnd,
                                        param.getModelPar(), param.isArea(), bdmsFbcOceanmodelB);
                                //上传nhup1.txt文件
                                code = calUtil.fileUpload(centerUrl.getEfileUrl(), token, nhup, linuxPath);
                                if (code != null && Objects.equals(code, "0")) {
                                    System.out.println("上传成功");
                                } else {
                                    jsonResult.setRemark("上传nhup1.txt文件失败");
                                    return jsonResult;
                                }
                                //提交模型计算作业
                                jobId = calUtil.modelCalculate(centerUrl.getHpcUrl(), token, modelConfig, workPath);
                                bdmsCalculateschemeM1 = calUtil.insertProject(param, uuid,
                                        bdmsFbcOceanmodelB, bdmsFbcTfpathFs.get(bdmsFbcTfpathFs.size() - 1).getForecasttm(), jobId);
                                bdms_calculatescheme_mService.insertBdmsCalculateschemeM(bdmsCalculateschemeM1);
                            }
                            if (jobId != null && !"".equals(jobId)) {
                                jsonResult.setData(uuid);
                                jsonResult.setRemark("已驱动模型计算，请使用计算方案id调用获取模型计算状态接口查询计算状态");
                                for (int i = 0; i < 1; i++) {
                                    modelService.queryByStatus(uuid, centerUrl, token, jobId, localPath,
                                            linuxPath, param.getModelId());
                                }
                                return jsonResult;
                            } else {
                                jsonResult.setRemark("模型计算作业失败");
                                return jsonResult;
                            }
                        case "HHUCCHAOSUANNS"://南海曙光超算
                            //预报路径
                            bdmsFbcTfpathFs = bdmsFbcTfpathFService.forecastPath(param.getTfid(),
                                    param.getTyphoonDepart(), param.getForecastTime());
                            if (bdmsFbcTfpathFs == null || bdmsFbcTfpathFs.size() == 0) {
                                jsonResult.setRemark("该台风实测路径点没有对应的中国台预见期数据");
                                return jsonResult;
                            }
                            for (BDMS_FBC_TFPATH_F bdmsFbcTfpathF : bdmsFbcTfpathFs) {
                                if (bdmsFbcTfpathF.getPressure() == null || bdmsFbcTfpathF.getPressure() == 0) {
                                    jsonResult.setRemark("预报路径气压数据不完整");
                                    return jsonResult;
                                }
                            }
                            bdmsFbcTfpathRs = bdmsFbcTfpathRService.getTyphoonIdPath(param.getTfid(),
                                    param.getForecastTime());
                            if (bdmsFbcTfpathRs == null || bdmsFbcTfpathRs.size() == 0) {
                                jsonResult.setRemark("获取台风实测路径失败");
                                return jsonResult;
                            }else {
                                for (BDMS_FBC_TFPATH_R bdmsFbcTfpathR : bdmsFbcTfpathRs) {
                                    if (bdmsFbcTfpathR.getPressure() == null || bdmsFbcTfpathR.getPressure() == 0) {
                                        jsonResult.setRemark("实测路径气压数据不完整");
                                        return jsonResult;
                                    }
                                }
                            }
                            nhupStart = param.getForecastTime();
                            String nhupStart1 = timeUtil.dateAddDay(nhupStart,-1);
                            nhupEnd = bdmsFbcTfpathFs.get(bdmsFbcTfpathFs.size() - 1).getForecasttm();
                            //生成discbase文件
                            TimeObject s1 = timeUtil.currentTimes(nhupStart);
                            startTime = "2088-" + s1.getMonth() + "-" + s1.getDay() + " 00:00:00";
                            String fTime = timeUtil.dateAddDay(startTime,-1);
                            s1 = timeUtil.currentTimes(nhupEnd);
                            endTime = "2088-" + s1.getMonth() + "-" + s1.getDay() + " 00:00:00";
                            List<BdmsStatisticalData> bdmsStatisticalData =
                                    bdmsStatisticalDataService.queryId(fTime,endTime);
                            File discbase = calUtil.creatediscbase(bdmsStatisticalData,localPath,nhupStart1);
                            code = calUtil.fileUpload(centerUrl.getEfileUrl(), token, discbase, linuxPath);
                            if (code != null && Objects.equals(code, "0")) {
                                System.out.println("上传成功");
                            } else {
                                jsonResult.setRemark("上传tfpath.dat文件失败");
                                return jsonResult;
                            }
                            //生成tfpath.dat文件
                            tfpath = calUtil.createTfpathFile(bdmsFbcTfpathRs, bdmsFbcTfpathFs,
                                    localPath,param.getForecastTime());
                            //上传tfpath.dat文件
                            code = calUtil.fileUpload(centerUrl.getEfileUrl(), token, tfpath, linuxPath);
                            if (code != null && Objects.equals(code, "0")) {
                                System.out.println("上传成功");
                            } else {
                                jsonResult.setRemark("上传tfpath.dat文件失败");
                                return jsonResult;
                            }
                            //生成nhup1.txt文件
                            nhup = calUtil.createNhup1File(nhupStart, localPath, nhupEnd,
                                    param.getModelPar(), param.isArea(), bdmsFbcOceanmodelB);
                            //上传nhup1.txt文件
                            code = calUtil.fileUpload(centerUrl.getEfileUrl(), token, nhup, linuxPath);
                            if (code != null && Objects.equals(code, "0")) {
                                System.out.println("上传成功");
                            } else {
                                jsonResult.setRemark("上传nhup1.txt文件失败");
                                return jsonResult;
                            }
                            //提交模型计算作业
                            jobId = calUtil.modelCalculate(centerUrl.getHpcUrl(), token, modelConfig, workPath);
                            bdmsCalculateschemeM1 = calUtil.insertProject(param, uuid,
                                    bdmsFbcOceanmodelB, bdmsFbcTfpathFs.get(bdmsFbcTfpathFs.size() - 1).getForecasttm(), jobId);
                            bdms_calculatescheme_mService.insertBdmsCalculateschemeM(bdmsCalculateschemeM1);
                            if (jobId != null && !"".equals(jobId)) {
                                jsonResult.setData(uuid);
                                jsonResult.setRemark("已驱动模型计算，请使用计算方案id调用获取模型计算状态接口查询计算状态");
                                for (int i = 0; i < 1; i++) {
                                    modelService.queryByStatus(uuid, centerUrl, token, jobId, localPath,
                                            linuxPath, param.getModelId());
                                }
                                return jsonResult;
                            } else {
                                jsonResult.setRemark("模型计算作业失败");
                                return jsonResult;
                            }
                        case "JSChangJiang"://沿江风暴潮模型
                            bdmsFbcTfpathFs = bdmsFbcTfpathFService.forecastPath(param.getTfid(),
                                    param.getTyphoonDepart(), param.getForecastTime());
                            if (bdmsFbcTfpathFs == null || bdmsFbcTfpathFs.size() == 0) {
                                jsonResult.setRemark("该台风实测路径点没有对应的中国台预见期数据");
                                return jsonResult;
                            }
                            for (BDMS_FBC_TFPATH_F bdmsFbcTfpathF : bdmsFbcTfpathFs) {
                                if (bdmsFbcTfpathF.getPressure() == null || bdmsFbcTfpathF.getPressure() == 0) {
                                    jsonResult.setRemark("预报路径气压数据不完整");
                                    return jsonResult;
                                }
                            }
                            bdmsFbcTfpathRs = bdmsFbcTfpathRService.getTyphoonIdPath(param.getTfid(),
                                    param.getForecastTime());
                            if (bdmsFbcTfpathRs == null || bdmsFbcTfpathRs.size() == 0) {
                                jsonResult.setRemark("获取台风实测路径失败");
                                return jsonResult;
                            }
                            nhupStart = param.getForecastTime();
                            nhupEnd = bdmsFbcTfpathFs.get(bdmsFbcTfpathFs.size() - 1).getForecasttm();
                            //生成disbase.dat文件
                            List<ST_RIVER_R> stRiverRs = stRiverRService.queryModel(nhupStart,nhupEnd);
                            if (stRiverRs != null && stRiverRs.size() > 0) {
                                File disbase = calUtil.createDisbase(stRiverRs,localPath);
                                code = calUtil.fileUpload(centerUrl.getEfileUrl(), token, disbase, linuxPath);
                            }else {
                                TimeObject s = timeUtil.currentTimes(nhupStart);
                                startTime = "2021-" + s.getMonth() + "-" + s.getDay();
                                s = timeUtil.currentTimes(nhupEnd);
                                endTime = "2021-" + s.getMonth() + "-" + s.getDay();
                                List<HY_DQ_C> hyDqCs = hyDqCService.queryModel(startTime,endTime);
                                File disbase = calUtil.createDisbaseA(hyDqCs,localPath,nhupStart);
                                code = calUtil.fileUpload(centerUrl.getEfileUrl(), token, disbase, linuxPath);
                            }
                            if (code != null && Objects.equals(code, "0")) {
                                System.out.println("上传成功");
                            } else {
                                jsonResult.setRemark("上传disbase.dat文件失败");
                                return jsonResult;
                            }
                            String linuxPath1 = linuxPath + "/" + "Large";
                            //生成tfpath.dat文件
                            tfpath = calUtil.createTfpathFile(bdmsFbcTfpathRs, bdmsFbcTfpathFs,
                                    localPath,param.getForecastTime());
                            //上传tfpath.dat文件
                            code = calUtil.fileUpload(centerUrl.getEfileUrl(), token, tfpath, linuxPath1);
                            if (code != null && Objects.equals(code, "0")) {
                                System.out.println("上传成功");
                            } else {
                                jsonResult.setRemark("上传tfpath.dat文件失败");
                                return jsonResult;
                            }
                            //生成nhup1.txt文件
                            nhup = calUtil.createNhup1File(nhupStart, localPath, nhupEnd,
                                    param.getModelPar(), param.isArea(), bdmsFbcOceanmodelB);
                            //上传nhup1.txt文件
                            code = calUtil.fileUpload(centerUrl.getEfileUrl(), token, nhup, linuxPath1);
                            if (code != null && Objects.equals(code, "0")) {
                                System.out.println("上传成功");
                            } else {
                                jsonResult.setRemark("上传nhup1.txt文件失败");
                                return jsonResult;
                            }
                            //提交模型计算作业
                            jobId = calUtil.modelCalculate(centerUrl.getHpcUrl(), token, modelConfig, workPath);
                            bdmsCalculateschemeM1 = calUtil.insertProject(param, uuid,
                                    bdmsFbcOceanmodelB, bdmsFbcTfpathFs.get(bdmsFbcTfpathFs.size() - 1).getForecasttm(), jobId);
                            bdms_calculatescheme_mService.insertBdmsCalculateschemeM(bdmsCalculateschemeM1);
                            if (jobId != null && !"".equals(jobId)) {
                                jsonResult.setData(uuid);
                                jsonResult.setRemark("已驱动模型计算，请使用计算方案id调用获取模型计算状态接口查询计算状态");
                                for (int i = 0; i < 1; i++) {
                                    modelService.queryByStatus(uuid, centerUrl, token, jobId, localPath,
                                            linuxPath, param.getModelId());
                                }
                                return jsonResult;
                            } else {
                                jsonResult.setRemark("模型计算作业失败");
                                return jsonResult;

                            }
                        case "HoHaiSmartZs": //智能预报模型
                            nhupStart = timeUtil.dateAddHour(param.getForecastTime(),-11);
                            nhupEnd = timeUtil.dateAddHour(param.getForecastTime(),24);
                            bdmsFbcTfpathRs = bdmsFbcTfpathRService.searchAllByTfid(param.getTfid(),
                                    nhupStart,nhupEnd);
                            //生成nhup1文件
                            File localPathNhup = createFileUtil.createNuhp1(nhupStart,nhupEnd,localPath);
                            //上传nhup1文件
                            uploadUtil.upload(centerUrl.getEfileUrl(),token,localPathNhup,linuxPath);
                            //生成tfpath.dat文件
                            tfpath = createFileUtil.createTfpathFile(bdmsFbcTfpathRs,localPath);
                            //上传tfpath.dat文件
                            uploadUtil.upload(centerUrl.getEfileUrl(),token,tfpath,linuxPath);
                            //生成bdms_st_astrotd_f.txt文件
                            fList = bdmsStAstrotdFService.tide_output(
                                    timeUtil.dateAddHour(param.getForecastTime(),-23), nhupEnd);
                            astrotd = createFileUtil.createAstrotd(fList, localPath);
                            //上传bdms_st_astrotd_f.txt文件
                            uploadUtil.upload(centerUrl.getEfileUrl(),token,astrotd,linuxPath);
                            //生成st_tide_r.txt文件
                            rList = modelService.createTide(param.getProjectId(),
                                    timeUtil.dateAddHour(param.getForecastTime(),-23), param.getForecastTime());
                            tide = createFileUtil.createTide(rList, localPath);
                            //上传st_tide_r.txt文件
                            uploadUtil.upload(centerUrl.getEfileUrl(),token,tide,linuxPath);
                            //提交模型计算作业
                            //calUtil.modelCalculatezs(centerUrl.getHpcUrl(), token, modelConfig, workPath);
                            jobId = calUtil.modelCalculatecw(centerUrl.getHpcUrl(), token, modelConfig, workPath);
                            bdmsCalculateschemeM1 = calUtil.insertProject(param, uuid, bdmsFbcOceanmodelB,
                                    nhupEnd,jobId);
                            bdms_calculatescheme_mService.insertBdmsCalculateschemeM(bdmsCalculateschemeM1);
                            if (jobId != null && !"".equals(jobId)) {
                                jsonResult.setData(uuid);
                                jsonResult.setRemark("已驱动模型计算，请使用计算方案id调用获取模型计算状态接口查询计算状态");
                                for (int i = 0; i < 1; i++) {
                                    modelService.queryByStatus(uuid, centerUrl, token, jobId, localPath,
                                            linuxPath, param.getModelId());
                                }
                                return jsonResult;
                            } else {
                                jsonResult.setRemark("模型计算作业失败");
                                return jsonResult;
                            }
                        case "HoHaiRevise": //智能校正模型
                            nhupStart = timeUtil.dateAddHour(param.getForecastTime(),-23);
                            nhupEnd = timeUtil.dateAddHour(param.getForecastTime(),24);
                            //生成bdms_st_astrotd_f.txt文件
                            fList = bdmsStAstrotdFService.tide_output(nhupStart, nhupEnd);
                            astrotd = createFileUtil.createAstrotd(fList, localPath);
                            //上传bdms_st_astrotd_f.txt文件
                            uploadUtil.upload(centerUrl.getEfileUrl(),token,astrotd,linuxPath);
                            //生成st_tide_r.txt文件
                            rList = modelService.createTide(param.getProjectId(),nhupStart,
                                    param.getForecastTime());
                            tide = createFileUtil.createTide(rList, localPath);
                            //上传st_tide_r.txt文件
                            uploadUtil.upload(centerUrl.getEfileUrl(),token,tide,linuxPath);
                            //提交模型计算作业
                            jobId = calUtil.modelCalculatexz(centerUrl.getHpcUrl(), token, modelConfig, workPath);
                            bdmsCalculateschemeM1 = calUtil.insertProject(param, uuid, bdmsFbcOceanmodelB,
                                    nhupEnd,jobId);
                            bdms_calculatescheme_mService.insertBdmsCalculateschemeM(bdmsCalculateschemeM1);
                            if (jobId != null && !"".equals(jobId)) {
                                jsonResult.setData(uuid);
                                jsonResult.setRemark("已驱动模型计算，请使用计算方案id调用获取模型计算状态接口查询计算状态");
                                for (int i = 0; i < 1; i++) {
                                    modelService.queryByStatus(uuid, centerUrl, token, jobId, localPath,
                                            linuxPath, param.getModelId());
                                }
                                return jsonResult;
                            } else {
                                jsonResult.setRemark("模型计算作业失败");
                                return jsonResult;
                            }
                        default:
                            jsonResult.setRemark("查询模型失败");
                            return jsonResult;
                    }
                } else {
                    jsonResult.setRemark("复制模型文件夹作业失败");
                    return jsonResult;
                }
            } else {
                jsonResult.setRemark("创建文件夹作业失败");
                return jsonResult;
            }
        }else {
            //1.定义目标路径
            String cschemePath = modelConfig.getLocalPath() + uuid;
            //创建文件夹
            DosUtil.execute("mkdir " + cschemePath);
            //2.定义需要复制文件路径
            String modelPath = "/home/hhdx/model/ns-tide-surge-flood";
            DosUtil.execute("cp -r " + modelPath + " " + cschemePath);
            //3.定义模型内部路径
            String modelPathn = cschemePath + "/ns-tide-surge-flood";
            //3.获取台风路径。创建tfpath文件
            List<BDMS_FBC_TFPATH_F> bdmsFbcTfpathFs = bdmsFbcTfpathFService.forecastPath(param.getTfid(), param.getTyphoonDepart(), param.getForecastTime());
            if (bdmsFbcTfpathFs == null || bdmsFbcTfpathFs.size() == 0) {
                jsonResult.setRemark("该台风实测路径点没有对应的中国台预见期数据");
                return jsonResult;
            }
            for (BDMS_FBC_TFPATH_F bdmsFbcTfpathF : bdmsFbcTfpathFs) {
                if (bdmsFbcTfpathF.getPressure() == null || bdmsFbcTfpathF.getPressure() == 0) {
                    jsonResult.setRemark("预报路径气压数据不完整");
                    return jsonResult;
                }
            }
            List<BDMS_FBC_TFPATH_R> bdmsFbcTfpathRs = bdmsFbcTfpathRService.getTyphoonIdPath(param.getTfid(),
                    param.getForecastTime());
            if (bdmsFbcTfpathRs == null || bdmsFbcTfpathRs.size() == 0) {
                jsonResult.setRemark("获取台风实测路径失败");
                return jsonResult;
            }else {
                for (BDMS_FBC_TFPATH_R bdmsFbcTfpathR : bdmsFbcTfpathRs) {
                    if (bdmsFbcTfpathR.getPressure() == null || bdmsFbcTfpathR.getPressure() == 0) {
                        jsonResult.setRemark("实测路径气压数据不完整");
                        return jsonResult;
                    }
                }
            }
            //生成tfpath.dat文件
            File tfpath = calUtil.createTfpathFile(bdmsFbcTfpathRs, bdmsFbcTfpathFs, modelPathn, param.getForecastTime());
            //生成discbase文件
            String nhupStart = param.getForecastTime();
            String nhupStart1 = timeUtil.dateAddDay(nhupStart,-1);
            String nhupEnd = bdmsFbcTfpathFs.get(bdmsFbcTfpathFs.size() - 1).getForecasttm();
            TimeObject s1 = timeUtil.currentTimes(nhupStart);
            String startTime = "2088-" + s1.getMonth() + "-" + s1.getDay() + " 00:00:00";
            String fTime = timeUtil.dateAddDay(startTime,-1);
            s1 = timeUtil.currentTimes(nhupEnd);
            String endTime = "2088-" + s1.getMonth() + "-" + s1.getDay() + " 00:00:00";
            List<BdmsStatisticalData> bdmsStatisticalData = bdmsStatisticalDataService.queryId(fTime,endTime);
            File discbase = calUtil.creatediscbase(bdmsStatisticalData, modelPathn, nhupStart1);
            //生成nhup1.txt文件
            File nhup = calUtil.createNhup1File(nhupStart, modelPathn, nhupEnd, param.getModelPar(), param.isArea(), bdmsFbcOceanmodelB);
            //方案入库
            BDMS_CALCULATESCHEME_M1 bdmsCalculateschemeM1 = calUtil.insertProject(param, uuid,
                    bdmsFbcOceanmodelB, bdmsFbcTfpathFs.get(bdmsFbcTfpathFs.size() - 1).getForecasttm(), "");
            bdms_calculatescheme_mService.insertBdmsCalculateschemeM(bdmsCalculateschemeM1);
            //模型计算
            modelService.queryByStatus2(modelPathn, uuid, param.getModelId());
            jsonResult.setData(uuid);
            jsonResult.setRemark("已驱动模型计算，请使用计算方案id调用获取模型计算状态接口查询计算状态");
            return jsonResult;
        }
    }

    @GetMapping(value = "/Forecast/TestRun", headers = "Accept=application/json")
    public JsonResult testRun(@RequestParam String path){
        JsonResult jsonResult = new JsonResult();
        jsonResult.setStatusCode(200);
        jsonResult.setSucceeded(true);
        DosUtil.execute2(path);
        return jsonResult;
    }
    /**
     *获取计算结果
     *@param calSchemeId 获取计算方案id
     */
    @RequestMapping(value = "/Forecast/SaveCalResultByDomain",method = RequestMethod.GET, headers = "Accept=application/json")
    public JsonResult saveModelCalResult(@RequestParam String calSchemeId,
                                         @RequestParam String areaName){
        JsonResult jsonResult = new JsonResult();
        jsonResult.setStatusCode(200);
        jsonResult.setSucceeded(true);
        TimeUtil timeUtil = new TimeUtil();
        if (modelConfig.getType() == 1) {
            if (calSchemeId != null && !"".equals(calSchemeId)) {
                //获取计算方案信息
                BDMS_CALCULATESCHEME_M1 bdmsCalculateschemeM1 = bdms_calculatescheme_mService.selcalSchemeId(calSchemeId);
                if (bdmsCalculateschemeM1 != null) {
                    //查询对应模型信息
                    BDMS_FBC_OCEANMODEL_B bdmsFbcOceanmodelB = bdms_fbc_oceanmodel_bService.
                            getModelInfo(bdmsCalculateschemeM1.getPid(),bdmsCalculateschemeM1.getMdid());
                    //模型在超算上对应的数据文件夹地址
                    String linuxPath = modelConfig.getUserpathname() +"model/caltmp/" + calSchemeId + "/" +
                            bdmsFbcOceanmodelB.getFoldernm();
                    CalUtil calUtil = new CalUtil();
                    DownloadUtil downloadUtil = new DownloadUtil();
                    String token = calUtil.getToken(modelConfig);//获取token
                    if (token != null && !"".equals(token)) {
                        CenterUrl centerUrl = calUtil.getCenter(token,modelConfig);//获取授权区域地址center
                        boolean result;
                        String localPath = modelConfig.getLocalPath() + File.separator +
                                calSchemeId;
                        if ("1".equals(bdmsCalculateschemeM1.getIsarea())) {
                            List<BDMS_FBC_RESULT_A> as = bdms_fbc_result_aService.queryByCschemeId(calSchemeId);
                            if (as != null && as.size() > 0) {
                                jsonResult.setRemark("数据已存在");
                            }else {
                                switch (bdmsCalculateschemeM1.getMdid()){
                                    case "HHUCCHAOSUANNS"://超算模型
                                    case "HHUCCHAOSUAN":
                                    case "JSCoastSurge":
                                    case "JSChangJiang":
                                        boolean exist = calUtil.fileExist(centerUrl.getEfileUrl(),
                                                token,linuxPath + "/fort.63");
                                        if (exist) {
                                            result = downloadUtil.downloadFort63(centerUrl.getEfileUrl(),token,
                                                    linuxPath,localPath);
                                            if (result) {
                                                for (int i = 0; i < 1; i++) {
                                                    bdms_fbc_result_aService.insertCalResultByCSDomain(localPath + File.separator + "fort.63",
                                                            timeUtil.dateAddHour(bdmsCalculateschemeM1.getDtmforecast(),bdmsFbcOceanmodelB.getOutstartindexArea()),
                                                            calSchemeId,areaName,bdmsCalculateschemeM1.getMdid());
                                                }
                                                jsonResult.setRemark("预报场数据正在入库...");
                                            }else {
                                                bdms_calculatescheme_mService.updateArea("3",calSchemeId);
                                                jsonResult.setRemark("下载数据失败");
                                            }
                                        }else {
                                            jsonResult.setRemark("模型计算错误，未找到预报场数据文件");
                                        }
                                        break;
                                    case "HoHaiSouthSeaZs"://南海模型
                                    case "HoHaiEastSeaZS"://东海模型
                                        //获取文件列表
                                        List<String> filePaths = calUtil.fileList(centerUrl.getEfileUrl(),token,linuxPath);
                                        if (filePaths != null && filePaths.size() > 0) {
                                            for (int i = 0; i < 1; i++) {
                                                bdms_fbc_result_aService.insertByDomain(filePaths,centerUrl.getEfileUrl(),
                                                        token,localPath,calSchemeId,areaName,bdmsFbcOceanmodelB,
                                                        bdmsCalculateschemeM1);
                                                jsonResult.setRemark("预报场数据正在入库...");
                                            }
                                        }else {
                                            jsonResult.setRemark("模型计算错误，未找到预报场数据文件");
                                        }
                                        break;
                                    default:
                                        jsonResult.setRemark("预报场数据入库失败，未找到对应模型");
                                        break;
                                }
                            }
                        }else {
                            jsonResult.setRemark("该计算方案没有输出场数据");
                        }
                    }else {jsonResult.setRemark("获取token失败");}
                }else {jsonResult.setRemark("该计算方案信息为空");}
            }else {jsonResult.setRemark("参数错误");}
        }else {
            String cschemePath = modelConfig.getLocalPath() + calSchemeId;
            String modelPathn = cschemePath + "/ns-tide-surge-flood";
            String fort63 = modelPathn + "/fort.63";
            //1.判断文件是否存在南沙
            if (new File(fort63).exists()) {
                BDMS_CALCULATESCHEME_M1 bdmsCalculateschemeM1 = bdms_calculatescheme_mService.selcalSchemeId(calSchemeId);
                if (bdmsCalculateschemeM1 != null) {
                    if (Integer.parseInt(bdmsCalculateschemeM1.getIsarea()) == 2) {
                        jsonResult.setRemark("数据已入库");
                    }else {
                        BDMS_FBC_OCEANMODEL_B bdmsFbcOceanmodelB = bdms_fbc_oceanmodel_bService.getModelInfo(bdmsCalculateschemeM1.getPid(),bdmsCalculateschemeM1.getMdid());
                        bdms_fbc_result_aService.insertCalResultByCSDomain(fort63, timeUtil.dateAddHour(bdmsCalculateschemeM1.getDtmforecast(),bdmsFbcOceanmodelB.getOutstartindexArea()),
                                calSchemeId,areaName,bdmsCalculateschemeM1.getMdid());
                        jsonResult.setRemark("预报场数据正在入库...");
                    }
                }
            }else {
                jsonResult.setRemark("文件不存在");
            }

        }
        return jsonResult;
    }
    /**
     *获取模型计算状态
     * @param calSchemeId 计算方案id
     */
    @RequestMapping(value = "/Forecast/GetCalSchemeInfoByStatute",method = RequestMethod.GET, headers = "Accept=application/json")
    public JsonResult getCalSchemeInfoByStatute(@RequestParam String calSchemeId){
        JsonResult jsonResult = new JsonResult();
        jsonResult.setStatusCode(200);
        jsonResult.setSucceeded(true);
        if (calSchemeId != null && !"".equals(calSchemeId)) {
            BDMS_CALCULATESCHEME_M1 bdmsCalculateschemeM1 = bdms_calculatescheme_mService.
                    selcalSchemeId(calSchemeId);
            if (bdmsCalculateschemeM1 != null) {
                switch (bdmsCalculateschemeM1.getState()){
                    case "3":
                        jsonResult.setData(3);
                        jsonResult.setRemark("计算完成,预报站点数据已保存，可调用获取预报站点的计算结果接口进行查询；" +
                                "预报场数据未保存,可调用保存预报场的计算结果接口进行保存");
                        break;
                    case "1":
                        jsonResult.setData(1);
                        jsonResult.setRemark("计算中");
                        break;
                    default:
                        jsonResult.setData(2);
                        jsonResult.setRemark("计算失败");
                        break;
                }
            }
        }
        return jsonResult;
    }
}
